package org.richin.crypto.util;

//字节数组及字符串转换类
import java.io.ByteArrayOutputStream;
import java.io.IOException;

public class Base64 {
	private final static char[] BASE64_ENCODING_TABLE;
    private final static byte[] BASE64_DECODING_TABLE;

    static 
    {
        BASE64_ENCODING_TABLE="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
        BASE64_DECODING_TABLE=new byte[]
        {
            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
            -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,
            -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,
            -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1
        };
    }
    /**
     * 将字符串进行Base64编码。
     * @param str 字符串
     * @return 编码后的字符串
     */
    public final static String encode(String str)
    {
        return encode(str.getBytes());
    }
    
	public static String encode(byte[] data) {
		StringBuffer sb = new StringBuffer();
		int len = data.length;
		int i = 0;
		int b1, b2;

		while (i < len) {
			byte ms = data[i];
			b1 = (ms >>> 4) & 0xf;// 高四位
			b2 = ms & 0xf;// 低四位
			sb.append(Integer.toHexString(b1));
			sb.append(Integer.toHexString(b2));
			i++;
		}
		return sb.toString();
	}
	 /**
     * 将数据进行Base64编码。
     * @param data 数据
     * @param offset 数据中的初始偏移量
     * @param length 写入的字节数
     * @return 编码后的字符串
     */
    public final static String encode(byte[] data,int offset,int length)
    {
        if(data==null)
        {
            return null;
        }
        
        StringBuffer buffer=new StringBuffer();
        int[] temp=new int[3];
        int end=offset+length;
        
        while(offset<end)
        {            
            temp[0]=data[offset++]&255;
            
            if(offset==data.length)
            {
                buffer.append(BASE64_ENCODING_TABLE[(temp[0]>>>2)&63]);
                buffer.append(BASE64_ENCODING_TABLE[(temp[0]<<4)&63]);
                buffer.append('=');
                buffer.append('=');
                
                break;
            }
            
            temp[1]=data[offset++]&255;
            
            if(offset==data.length)
            {
                buffer.append(BASE64_ENCODING_TABLE[(temp[0]>>>2)&63]);
                buffer.append(BASE64_ENCODING_TABLE[((temp[0]<<4)|(temp[1]>>>4))&63]);
                buffer.append(BASE64_ENCODING_TABLE[(temp[1]<<2)&63]);
                buffer.append('=');
                
                break;
            }
            
            temp[2]=data[offset++]&255;
            
            buffer.append(BASE64_ENCODING_TABLE[(temp[0]>>>2)&63]);
            buffer.append(BASE64_ENCODING_TABLE[((temp[0]<<4)|(temp[1]>>>4))&63]);
            buffer.append(BASE64_ENCODING_TABLE[((temp[1]<<2)|(temp[2]>>>6))&63]);
            buffer.append(BASE64_ENCODING_TABLE[temp[2]&63]);
        }
        
        return buffer.toString();
    }
    
	public static byte[] decode(String str) throws IOException {
		int len = str.length();
		ByteArrayOutputStream buf = new ByteArrayOutputStream(len);
		int i = 0;
		if (len % 2 != 0) {
			throw new IOException("输入的长度只能为偶数!");
		}

		while (i < len) {
			String tmp_hight = str.substring(i, i + 1);
			String tmp = str.substring(i, i + 2);
			System.out.println(tmp_hight);
			int dec_sign = Integer.parseInt(tmp_hight, 16) >>> 3;
			int dec = 0;
			if (dec_sign == 1) {
				dec = Integer.parseInt(tmp, 16) ^ 0xff;
				dec = dec + 1;
				dec = -dec;
			} else {
				dec = Integer.parseInt(tmp, 16);
			}

			buf.write(dec);
			i = i + 2;
		}
		return buf.toByteArray();
	}

	public static String getBase64Encode(byte[] src) throws Exception {
		try {
			return Base64.encode(src);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	public static byte[] getBase64Dencode(String src) throws Exception {
		try {
			return Base64.decode(src);
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		}
	}

	public static void main(String[] args) {
		
	}
}
